﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Reflection;

namespace System
{
    /// <summary>
    /// Control extension methods
    /// </summary>
    public static class ControlExt
    {
        /// <summary>
        /// Determines whether [has child in region] [the specified control].
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="p">The p.</param>
        /// <param name="s">The s.</param>
        /// <returns></returns>
        public static bool HasChildInRegion(this Control control, System.Drawing.Point p, System.Drawing.Size s)
        {
            foreach (Control c in control.Controls)
                if (c.Bounds.IntersectsWith(new Rectangle(p, s)))
                    return true;
            return false;
        }
        /// <summary>
        /// Determines whether [is design mode] [the specified c].
        /// </summary>
        /// <param name="c">The c.</param>
        /// <returns></returns>
        public static bool IsDesignMode(this Component c)
        {
            bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
            if (designMode)
                return true;

            return c.Site != null && (c.Site.DesignMode == true);
        }

        /// <summary>
        /// Gets the service.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="provider">The provider.</param>
        /// <returns></returns>
        public static T GetService<T>(this Component provider)
        {
            return (T)provider.RunMethod("GetService", (typeof(T)));
        }
        /// <summary>
        /// Gets the type.
        /// </summary>
        /// <param name="provider">The provider.</param>
        /// <param name="typeFullName">Full name of the type.</param>
        /// <param name="excludeGlobalTypes">if set to <c>true</c> [exclude global types].</param>
        /// <returns></returns>
        public static Type GetType(this Component provider, string typeFullName, bool excludeGlobalTypes = true)
        {
            if (provider != null)
            {
                Type t1 = Type.GetType(typeFullName);
                if (t1 != null)
                    return t1;
                ITypeDiscoveryService iTypeDiscoveryService = provider.GetService<ITypeDiscoveryService>();
                if (iTypeDiscoveryService != null)
                {
                    ICollection coll = iTypeDiscoveryService.GetTypes(typeof(object), excludeGlobalTypes);
                    foreach (Type t in coll)
                    {
                        if (t.FullName == typeFullName)
                        {
                            return t;
                        }
                    }
                }
                else
                {
                    System.Reflection.Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
                    foreach (Assembly a in ass)
                    {
                        if (!excludeGlobalTypes || !a.GlobalAssemblyCache)
                        {
                            t1 = a.GetType(typeFullName, false, false);
                            if (t1 != null)
                                return t1;
                        }
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// Gets the location.
        /// </summary>
        /// <param name="c">The c.</param>
        /// <returns></returns>
        public static string GetLocation(this Control c)
        {
            string path = "";
            if (c != null)
            {
                c = c.Parent;
                while (c != null)
                {
                    if (c.Text.IsNotNull())
                    {
                        if (path.IsNotNullOrEmpty())
                        {
                            path = " -> " + path;
                        }
                        path = c.Text.Trim().XReplace(" \\*", "") + path;
                    }
                    c = c.Parent;
                }
                return path;
            }
            return "";
        }
        /// <summary>
        /// Gets the full path.
        /// </summary>
        /// <param name="control">The control.</param>
        /// <returns></returns>
        public static string GetFullPath(this Control control)
        {
            Control c = control;
            string path = string.Empty;
            while (c != null)
            {
                path = c.Name + "." + path;
                c = c.Parent;
            }
            return path.Trim('.');
        }
    }
}
